package org.lanyu.springainovel.common.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.lanyu.springainovel.common.entity.AiMcp;
import org.lanyu.springainovel.common.entity.ServerConfig;
import org.lanyu.springainovel.common.event.McpStatusChangeEvent;
import org.lanyu.springainovel.common.event.ServerConfigChangeEvent;
import org.lanyu.springainovel.common.event.McpConfigRequestEvent;
import org.lanyu.springainovel.common.event.McpConfigResponseEvent;
import org.lanyu.springainovel.common.mapper.AiMcpMapper;
import org.lanyu.springainovel.common.util.ConversionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.List;

@Service
public class AiMcpService {

    private static final Logger logger = LoggerFactory.getLogger(AiMcpService.class);

    @Autowired
    private AiMcpMapper aiMcpMapper;

    @Autowired
    private ApplicationEventPublisher eventPublisher;

    @EventListener
    public void handleMcpConfigRequestEvent(McpConfigRequestEvent event) {
        logger.info("[事件监听器] AiMcpService.handleMcpConfigRequestEvent 被调用，事件�? {}", event.getSource());
        McpConfigRequestEvent.ConfigRequestType requestType = event.getRequestType();
        List<AiMcp> mcpList = null;

        try {
            switch (requestType) {
                case ALL_ENABLED:
                    logger.info("[事件监听器] 处理请求所有启用的MCP配置事件");
                    mcpList = getAllEnabledMcp();
                    break;
                case ALL_DISABLED:
                    logger.info("[事件监听器] 处理请求所有禁用的MCP配置事件");
                    mcpList = getAllDisabledMcp();
                    break;
                default:
                    logger.warn("[事件监听器] 未知的MCP配置请求类型: {}", requestType);
                    eventPublisher.publishEvent(new McpConfigResponseEvent(this, "未知的请求类�? " + requestType));
                    return;
            }

            if (mcpList != null) {
                logger.info("[事件监听器] 成功获取{}个MCP配置", mcpList.size());
                eventPublisher.publishEvent(new McpConfigResponseEvent(this, mcpList));
            } else {
                logger.warn("[事件监听器] 未找到MCP配置");
                eventPublisher.publishEvent(new McpConfigResponseEvent(this, "未找到MCP配置"));
            }
        } catch (Exception e) {
            logger.error("[事件监听器] 处理MCP配置请求事件失败: {}", e.getMessage());
            eventPublisher.publishEvent(new McpConfigResponseEvent(this, "获取MCP配置失败: " + e.getMessage()));
        }
    }

    /**
     * 处理MCP状态变更事�?     * <p>
     * 注意：enable和status的区�?     * <ul>
     * <li>enable：前端用户设置的MCP服务启用/禁用状�?/li>
     * <li>status：MCP服务的实际连接状�?/li>
     * </ul>
     */
    @EventListener
    public void handleMcpStatusChangeEvent(McpStatusChangeEvent event) {
        String serverName = event.getServerName();
        boolean enable = event.isEnable();
        boolean status = event.isStatus();
        AiMcp mcp = event.getMcp();

        logger.info("处理MCP服务[{}]状态变更事�? enable={}, status={}", serverName, enable, status);
        
        // 更新enable字段（用户设置的启用状态）
        if (mcp.getEnable() != (enable ? 1 : 0)) {
            mcp.setEnable(enable ? 1 : 0);
            logger.info("更新MCP服务[{}]的启用状态为: {}", serverName, enable ? "启用" : "禁用");
        }
        
        // 更新status字段（实际连接状态）
        if (mcp.getStatus() != (status ? 1 : 0)) {
            mcp.setStatus(status ? 1 : 0);
            logger.info("更新MCP服务[{}]的连接状态为: {}", serverName, status ? "连接成功" : "连接失败");
        }
        
        // 如果用户禁用了服务，则status也必须为禁用
        if (!enable && status) {
            mcp.setStatus(0);
            logger.info("用户禁用MCP服务[{}]，强制设置连接状态为失败", serverName);
        }
        
        mcp.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        aiMcpMapper.updateById(mcp);
    }

    public List<AiMcp> getAllEnabledMcp() {
        QueryWrapper<AiMcp> query = new QueryWrapper<>();
        query.eq("status", 1);
        query.eq("enable", 1);
        return aiMcpMapper.selectList(query);
    }

    /**
     * 查询已启用但服务不可用的服务
     * @return
     */
    public List<AiMcp> getAllDisabledMcp() {
        QueryWrapper<AiMcp> query = new QueryWrapper<>();
        query.eq("status", 0);
        query.eq("enable", 1);
        return aiMcpMapper.selectList(query);
    }

    public void addMcp(AiMcp mcp) {
        mcp.setUpdateTime(new Timestamp(System.currentTimeMillis()));

        // 从configJson中提取mcpServers作为mcp名称和类�?
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode root = objectMapper.readTree(mcp.getConfigJson());
            JsonNode serversNode = root.path("mcpServers");
            if (serversNode.isObject() && serversNode.size() > 0) {
                // 获取第一个服务器名称作为mcp名称
                String serverName = serversNode.fieldNames().next();
                mcp.setName(serverName);

                // 获取服务器类�?
                JsonNode serverNode = serversNode.path(serverName);
                String type = serverNode.path("type").asText("");
                // 自动检测npx类型
                if (type.isEmpty() && serverNode.has("command") && "npx".equals(serverNode.get("command").asText())) {
                    type = "npx";
                }
                if ("sse".equalsIgnoreCase(type) || "stdio".equalsIgnoreCase(type) || "npx".equalsIgnoreCase(type)) {
                    mcp.setContentType(type);
                }
            }
        } catch (Exception e) {
            logger.error("解析MCP配置失败: {}", e.getMessage());
        }

        aiMcpMapper.insert(mcp);
        // 只有当status=1且enable=1时才添加到缓�?
        if ((mcp.getStatus() == null || mcp.getStatus() == 1) && (mcp.getEnable() == null || mcp.getEnable() == 1)) {

            // 解析 configJson，提取所�?server
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                JsonNode root = objectMapper.readTree(mcp.getConfigJson());
                JsonNode serversNode = root.path("mcpServers");
                if (serversNode.isObject()) {
                    serversNode.fields().forEachRemaining(
                            new java.util.function.Consumer<java.util.Map.Entry<String, JsonNode>>() {
                        @Override
                        public void accept(java.util.Map.Entry<String, JsonNode> entry) {
                            String serverName = entry.getKey();
                            JsonNode serverNode = entry.getValue();
                            String type = serverNode.path("type").asText("");
                            // 自动检测npx类型
                            if (type.isEmpty() && serverNode.has("command") && "npx".equals(serverNode.get("command").asText())) {
                                type = "npx";
                            }
                            if ("sse".equalsIgnoreCase(type) || "stdio".equalsIgnoreCase(type) || "npx".equalsIgnoreCase(type)) {
                                ServerConfig config = ConversionUtil.parseServerConfigFromJson(serverName, serverNode, type);
                                if (config != null) {
                                    eventPublisher.publishEvent(new ServerConfigChangeEvent(AiMcpService.this, serverName, config));
                                }
                            }
                        }
                    });
                }
            } catch (Exception e) {
                logger.error("添加MCP服务器配置失�? {}", e.getMessage());
            }
        }
    }

    public void updateMcp(AiMcp mcp) {
        mcp.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        // 从configJson中提取mcpServers作为mcp名称
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode root = objectMapper.readTree(mcp.getConfigJson());
            JsonNode serversNode = root.path("mcpServers");
            if (serversNode.isObject() && serversNode.size() > 0) {
                // 获取第一个服务器名称作为mcp名称
                String serverName = serversNode.fieldNames().next();
                mcp.setName(serverName);

                // 获取服务器类�?
                JsonNode serverNode = serversNode.path(serverName);
                String type = serverNode.path("type").asText("");
                // 自动检测npx类型
                if (type.isEmpty() && serverNode.has("command") && "npx".equals(serverNode.get("command").asText())) {
                    type = "npx";
                }
                if ("sse".equalsIgnoreCase(type) || "stdio".equalsIgnoreCase(type) || "npx".equalsIgnoreCase(type)) {
                    mcp.setContentType(type);
                }
            }
        } catch (Exception e) {
            logger.error("解析MCP配置失败: {}", e.getMessage());
        }

        aiMcpMapper.updateById(mcp);

        // 解析 configJson，提取所�?server 并更新缓�?
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode root = objectMapper.readTree(mcp.getConfigJson());
            JsonNode serversNode = root.path("mcpServers");
            if (serversNode.isObject()) {
                serversNode.fields().forEachRemaining(
                        new java.util.function.Consumer<java.util.Map.Entry<String, JsonNode>>() {
                    @Override
                    public void accept(java.util.Map.Entry<String, JsonNode> entry) {
                        String serverName = entry.getKey();
                        JsonNode serverNode = entry.getValue();
                        String type = serverNode.path("type").asText("");
                        // 自动检测npx类型
                        if (type.isEmpty() && serverNode.has("command") && "npx".equals(serverNode.get("command").asText())) {
                            type = "npx";
                        }
                        if ("sse".equalsIgnoreCase(type) || "stdio".equalsIgnoreCase(type) || "npx".equalsIgnoreCase(type)) {
                            ServerConfig config = ConversionUtil.parseServerConfigFromJson(serverName, serverNode, type);
                            if (config != null) {
                                // 根据启用状态决定是添加还是移除服务�?
                                if ((mcp.getStatus() == null || mcp.getStatus() == 1) && (mcp.getEnable() == null || mcp.getEnable() == 1)) {
                                    eventPublisher.publishEvent(new ServerConfigChangeEvent(AiMcpService.this, serverName, config));
                                } else {
                                    eventPublisher.publishEvent(new ServerConfigChangeEvent(AiMcpService.this, serverName));
                                }
                            }
                        }
                    }
                });
            }
        } catch (Exception e) {
            logger.error("更新MCP服务器配置失�? {}", e.getMessage());
        }
    }

    /**
     * 更新MCP服务的启用状�?     * @param id 服务id
     * @param enable 是否启用(1启用�?禁用)
     */
    public void updateMcpEnableStatus(Long id, Integer enable) {
        AiMcp mcp = getById(id);
        if (mcp != null && mcp.getEnable() != enable) {
            mcp.setEnable(enable);
            mcp.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            aiMcpMapper.updateById(mcp);
            logger.info("更新MCP服务[{}]的启用状态为: {}", mcp.getName(),enable);

            // 解析 configJson，提取所�?server 并更新缓�?
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                JsonNode root = objectMapper.readTree(mcp.getConfigJson());
                JsonNode serversNode = root.path("mcpServers");
                if (serversNode.isObject()) {
                    serversNode.fields().forEachRemaining(
                            new java.util.function.Consumer<java.util.Map.Entry<String, JsonNode>>() {
                        @Override
                        public void accept(java.util.Map.Entry<String, JsonNode> entry) {
                            String serverName = entry.getKey();
                            JsonNode serverNode = entry.getValue();
                            String type = serverNode.path("type").asText("");
                            // 自动检测npx类型
                            if (type.isEmpty() && serverNode.has("command") && "npx".equals(serverNode.get("command").asText())) {
                                type = "npx";
                            }
                            if ("sse".equalsIgnoreCase(type) || "stdio".equalsIgnoreCase(type) || "npx".equalsIgnoreCase(type)) {
                                ServerConfig config = ConversionUtil.parseServerConfigFromJson(serverName, serverNode, type);
                                if (config != null) {
                                    // 根据启用状态决定是添加还是移除服务�?
                                    if ((mcp.getStatus() == null || mcp.getStatus() == 1) && enable == 1) {
                                        eventPublisher.publishEvent(new ServerConfigChangeEvent(AiMcpService.this, serverName, config));
                                    } else {
                                        eventPublisher.publishEvent(new ServerConfigChangeEvent(AiMcpService.this, serverName));
                                    }
                                }
                            }
                        }
                    });
                }
            } catch (Exception e) {
                logger.error("更新MCP启用状态失�? {}", e.getMessage());
            }
        }
    }

    public void deleteMcp(Long id) {
        AiMcp mcp = aiMcpMapper.selectById(id);
        if (mcp != null) {
            String mcpName = mcp.getName();
            // 解析 configJson，提取所�?server
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                JsonNode root = objectMapper.readTree(mcp.getConfigJson());
                JsonNode serversNode = root.path("mcpServers");
                if (serversNode.isObject()) {
                    serversNode.fields().forEachRemaining(
                            new java.util.function.Consumer<java.util.Map.Entry<String, JsonNode>>() {
                        @Override
                        public void accept(java.util.Map.Entry<String, JsonNode> entry) {
                            String serverName = entry.getKey();
                            eventPublisher.publishEvent(new ServerConfigChangeEvent(AiMcpService.this, serverName));
                        }
                    });
                }
            } catch (Exception e) {
                logger.error("删除MCP服务器配置失�? {}", e.getMessage());
            }

            // 从数据库中删�?
            aiMcpMapper.deleteById(id);
            logger.info("删除MCP服务: {}", mcpName);
        }
    }

    public AiMcp getById(Long id) {
        return aiMcpMapper.selectById(id);
    }

    public AiMcp getByName(String name) {
        QueryWrapper<AiMcp> query = new QueryWrapper<>();
        query.eq("name", name);
        return aiMcpMapper.selectOne(query);
    }

    public Page<AiMcp> pageQuery(String keyword, int page, int size) {
        QueryWrapper<AiMcp> query = new QueryWrapper<>();
        if (keyword != null && !keyword.isEmpty()) {
            query.and(qw -> qw.like("name", keyword).or().like("description", keyword));
        }
        query.orderByDesc("update_time");
        return aiMcpMapper.selectPage(new Page<>(page, size), query);
    }
}
